import config from './config/main';
import zlib from 'zlib';
import koa from 'koa';
import compress from 'koa-compress';
import cors from 'kcors';

import httpRouter from './routes/http_routes';
import mqRouter from './routes/mq_routes';
import wsRouter from './routes/ws_routes';

import logger from './middlewares/logger';
import wsm from './middlewares/wsm';
import dbm from './middlewares/dbm';
import mqm from './middlewares/mqm';
import mysql from './middlewares/mysql';
import redis from './middlewares/redis';
import wspool from './middlewares/wspool';

export const start = () => {
    const app = koa();

    const checkDomain = (str) => config.corsCheckDomain && config.corsCheckDomain.test(str);


    // public 日志插件, 跨域, 压缩, redis
    app
        .use(logger(app))
        .use(cors({
            origin: function* gen(ctx) {
                const reqReferer = 'referer' in ctx.headers ? ctx.headers.referer : null;
                const reqOrigin = 'origin' in ctx.headers ? ctx.headers.origin : null;
                if (!checkDomain(reqReferer)) return false;
                if (!checkDomain(reqOrigin)) return false;
                console.log('[cors] allowed: %s, referer: %s', reqOrigin, reqReferer);
                return reqOrigin;
            },
            allowMethods: 'GET,PUT,POST,DELETE',
            maxAge: 86400,
            credentials: true,
        }))
        .use(compress({
            filter: (contentType) => /text/i.test(contentType),
            threshold: 1100,
            flush: zlib.Z_SYNC_FLUSH,
        }))
        .use(dbm(app))
        .use(mysql(app))
        .use(redis(app))
        .use(wspool(app))
        .use(mqm(app, mqRouter));


    // web socket
    app
        .use(wsm(app, wsRouter, {
            heartbeat: false,
            heartbeatInterval: 5000,
        }));


    // restful http
    app
        .use(httpRouter.routes())
        .use(httpRouter.allowedMethods());

    app.listen(config.serverPort, config.serverHost, () => {
        console.log('[%s] server running at http://%s:%d/...',
            process.env.NODE_ENV, config.serverHost, config.serverPort);
    });
};

if (!module.parent) {
    start();
}
